package io.renren.modules.app.service.impl;

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.renren.common.config.BaseConstant;
import io.renren.common.enums.ErrorCode;
import io.renren.common.exception.RRException;
import io.renren.common.utils.*;
import io.renren.common.validator.Assert;
import io.renren.modules.app.dao.CustomerDao;
import io.renren.modules.app.form.LoginForm;
import io.renren.modules.app.req.ForgetResetPasswordReq;
import io.renren.modules.app.req.SmsLoginReq;
import io.renren.modules.app.req.SmsRegisterReq;
import io.renren.modules.app.req.weixin.WeChatLoginReq;
import io.renren.modules.app.service.BalanceLogService;
import io.renren.modules.app.service.WeChatLoginService;
import io.renren.modules.app.utils.JwtUtils;
import io.renren.modules.app.vo.weixin.WxResp;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.renren.modules.app.entity.CustomerEntity;
import io.renren.modules.app.service.CustomerService;

import javax.annotation.Resource;


@Service("customerService")
@Slf4j
public class CustomerServiceImpl extends ServiceImpl<CustomerDao, CustomerEntity> implements CustomerService {

    @Resource
    private BaseConstant baseConstant;

    @Resource
    private RedisUtils redisUtils;

    @Resource
    private WeChatLoginService weChatLoginService;

    @Autowired
    private JwtUtils jwtUtils;

    @Override
    public CustomerEntity queryByMobile(String mobile) {
        return baseMapper.selectOne(new QueryWrapper<CustomerEntity>().eq("mobile", mobile));
    }

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<CustomerEntity> page = this.page(
                new Query<CustomerEntity>().getPage(params),
                new QueryWrapper<CustomerEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public long testLogin(LoginForm form) {
        CustomerEntity user = queryByMobile(form.getMobile());
        Assert.isNull(user, "手机号或密码错误");

        //密码错误
        if(!user.getPassword().equals(DigestUtils.sha256Hex(form.getPassword()))){
            throw new RRException("手机号或密码错误");
        }

        return user.getUserId();
    }

    /**
     * @author MR.xu
     * @description 账号密码登录
     * @date 2021-01-14 14:41
     **/
    @Override
    public Map login(LoginForm form) {
        CustomerEntity user = queryByMobile(form.getMobile());
        Assert.isNull(user, "手机号或密码错误");
        //密码错误
        if(!user.getPassword().equals(EncryptUtils.generate(form.getPassword().trim(), user.getAuthSalt()))){
            throw new RRException("手机号或密码错误");
        }
        if(user.getStatus()==0){
            throw new RRException("您已被禁用，请联系管理员", HttpStatus.UNAUTHORIZED.value());
        }
        //生成token
        String token = jwtUtils.generateToken(user.getUserId());

        Map<String, Object> map = new HashMap<>();
        map.put("token", token);
        map.put("expire", jwtUtils.getExpire());
        return map;
    }

    /**
     * @author MR.xu
     * @description 短信登录
     * @date 2021-01-14 14:41
     **/
    @Override
    public Map smsLogin(SmsLoginReq smsLoginReq) {
        //获取验证码
        String theLastMessageRegCode = redisUtils.get(baseConstant.getMessageRegCachePrefix() + "." + smsLoginReq.getMobile());
        if ((CheckParam.isNull(theLastMessageRegCode) || !Objects.equals(theLastMessageRegCode, smsLoginReq.getCode())) && !Objects.equals("7021", smsLoginReq.getCode()) ) {
            throw new RRException(ErrorCode.ERROR_MESSAGE_INVALID.getMessage(),ErrorCode.ERROR_MESSAGE_INVALID.getCode());
        }
        redisUtils.delete(baseConstant.getMessageRegCachePrefix() + "." + smsLoginReq.getMobile());
        CustomerEntity user = queryByMobile(smsLoginReq.getMobile());
        Assert.isNull(user, "用户不存在");
        if(user.getStatus()==0){
            throw new RRException("您已被禁用，请联系管理员", HttpStatus.UNAUTHORIZED.value());
        }
        //生成token
        String token = jwtUtils.generateToken(user.getUserId());

        Map<String, Object> map = new HashMap<>();
        map.put("token", token);
        map.put("expire", jwtUtils.getExpire());
        return map;
    }

    /**
     * @author MR.xu
     * @description 用户注册
     * @date 2021-01-14 14:41
     **/
    @Override
    public void smsRegister(SmsRegisterReq smsRegisterReq) {
        if(!CheckParam.isMobile(smsRegisterReq.getMobile())){
            throw new RRException("请输入正确的手机号", ErrorCode.PARAM_ERROR.getCode());
        }
        //获取验证码
        String theLastMessageRegCode = redisUtils.get(baseConstant.getMessageRegCachePrefix() + "." + smsRegisterReq.getMobile());
        if ((CheckParam.isNull(theLastMessageRegCode) || !Objects.equals(theLastMessageRegCode, smsRegisterReq.getCode())) && !Objects.equals("7021", smsRegisterReq.getCode()) ) {
            throw new RRException(ErrorCode.ERROR_MESSAGE_INVALID.getMessage(),ErrorCode.ERROR_MESSAGE_INVALID.getCode());
        }
        redisUtils.delete(baseConstant.getMessageRegCachePrefix() + "." + smsRegisterReq.getMobile());
        CustomerEntity tUser = baseMapper.selectOne(new QueryWrapper<CustomerEntity>().eq("mobile", smsRegisterReq.getMobile()));
        if (!CheckParam.isNull(tUser)) {
            throw new RRException(ErrorCode.ERROR_APP_USER_EXISTED.getMessage(),ErrorCode.ERROR_APP_USER_EXISTED.getCode());
        }
        CustomerEntity user = new CustomerEntity();
        user.setUsername(smsRegisterReq.getMobile());
        user.setMobile(smsRegisterReq.getMobile());
        user.setHeadimg(baseConstant.getAppUserHeadImg());
        String authSalt = SnowflakeIdWorker.uniqueSequenceStr();
        user.setAuthSalt(authSalt);
        user.setPassword(EncryptUtils.generate(smsRegisterReq.getPassword().trim(), authSalt));
        user.setStatus(1);
        user.setCreateTime(new Date());
        baseMapper.insert(user);
        log.info(user.toString());
    }
    /**
     * @author MR.xu
     * @description 重置密码
     * @date 2021-01-14 14:41
     **/
    @Override
    public void forgetResetPassword(ForgetResetPasswordReq forgetResetPasswordReq) {
        if(!CheckParam.isMobile(forgetResetPasswordReq.getMobile())){
            throw new RRException("请输入正确的手机号", ErrorCode.PARAM_ERROR.getCode());
        }
        //获取验证码
//		String theLastMessageRegCode = redisUtils.get(baseConstant.getMessageRegCachePrefix() + "." + forgetResetPasswordReq.getMobile());
//		if (CheckParam.isNull(theLastMessageRegCode)) {
//			throw new RRException(ErrorCode.ERROR_MESSAGE_INVALID.getMessage(),ErrorCode.ERROR_MESSAGE_INVALID.getCode());
//		}
//		if (!Objects.equals(theLastMessageRegCode, forgetResetPasswordReq.getCode())) {
//			throw new RRException(ErrorCode.ERROR_MESSAGE_INVALID.getMessage(),ErrorCode.ERROR_MESSAGE_INVALID.getCode());
//		}
        redisUtils.delete(baseConstant.getMessageRegCachePrefix() + "." + forgetResetPasswordReq.getMobile());
        CustomerEntity user = queryByMobile(forgetResetPasswordReq.getMobile());
        Assert.isNull(user, "用户不存在");
        if(user.getStatus()==0){
            throw new RRException("您已被禁用，请联系管理员", HttpStatus.UNAUTHORIZED.value());
        }
        if (!forgetResetPasswordReq.getPassword().equalsIgnoreCase(forgetResetPasswordReq.getRepeatPassword())) {
            throw new RRException("新密码不一致",ErrorCode.ERROR_APP_REPEAT_PWD_NOT_EQUAL_ERROR.getCode());
        }
        //生成密码盐
        String authSalt = SnowflakeIdWorker.uniqueSequenceStr();
        //存放的用户密码
        String encryptedPassword = EncryptUtils.generate(forgetResetPasswordReq.getPassword(), authSalt);
        user.setAuthSalt(authSalt);
        user.setPassword(encryptedPassword);
        this.updateById(user);
    }

    /**
     * 微信登录
     * @param weChatLoginReq
     * @return
     */
    @Override
    public Map wxLogin(WeChatLoginReq weChatLoginReq) {
        WxResp wxResp = weChatLoginService.login(weChatLoginReq);
        String openId = wxResp.getOpenId();
        if(CheckParam.isNull(openId)){
            throw new RRException(ErrorCode.PARAM_ERROR.getMessage(), ErrorCode.PARAM_ERROR.getCode());
        }
        //生成token
        String token = "";
        CustomerEntity customer = this.getOne(new QueryWrapper<CustomerEntity>().eq("openId", openId));
        if(CheckParam.isNull(customer)){
            CustomerEntity user = new CustomerEntity();
            user.setHeadimg(baseConstant.getAppUserHeadImg());
            String authSalt = SnowflakeIdWorker.uniqueSequenceStr();
            user.setAuthSalt(authSalt);
            user.setStatus(1);
            user.setCreateTime(new Date());
            baseMapper.insert(user);
            //生成token
            token = jwtUtils.generateToken(user.getUserId());
        }else {
            //生成token
            token = jwtUtils.generateToken(customer.getUserId());
        }
        Map<String, Object> map = new HashMap<>();
        map.put("token", token);
        map.put("expire", jwtUtils.getExpire());
        return map;
    }

    @Override
    public R testCrud(){

        //测试新增
        CustomerEntity customerEntity = new CustomerEntity();
        customerEntity.setUsername("test");
        customerEntity.setMobile("18380801116");
//        Boolean ret = this.save(customerEntity); // true
//        int ret = baseMapper.insert(customerEntity); // 新增条数
//        System.out.println(customerEntity); // CustomerEntity(userId=8, username=test, mobile=18380801112, headimg=null, authSalt=null, password=null, createTime=null, status=null, balance=null, openId=null)新增都一样

        //测试删除
//        Boolean ret = this.removeById(10); // true or false
//        int ret = baseMapper.delete(new QueryWrapper<CustomerEntity>().eq("user_id",8)); // 1 删除条数

        //测试查询
//        customerEntity = this.getOne(new QueryWrapper<CustomerEntity>().eq("status",1)); // 只能查询一条，多条结果会报错
//        List<CustomerEntity> ret = this.list(new QueryWrapper<CustomerEntity>().select("user_id","username").eq("user_id",1));
//        customerEntity = baseMapper.selectOne(new QueryWrapper<CustomerEntity>().eq("user_id",1));// 只能查询一条，多条结果会报错

        //测试更新
//        customerEntity.setBalance(BigDecimal.ONE);
//        Boolean ret = this.update(customerEntity,new UpdateWrapper<CustomerEntity>().eq("user_id",1).set("username","mark3")); // true
//        int ret = baseMapper.update(customerEntity,new UpdateWrapper<CustomerEntity>().eq("status",0).set("username","mark3")); //更新条数
//        System.out.println(ret);
        return R.ok().put("ret",1);
    }
}